﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Newtonsoft.Json;
using System.Runtime.Serialization;
using System.IO;

namespace Fixx.DTO.Parser
{
	public static class FixxParser 
	{
		public static T Parse<T>(string source, FixxParserFormat format) where T : IFixxDalObject, new() 
		{
			return new FixxParser<T>().Parse(source,format);
		}
		public static IEnumerable<T> ParseIEnumerable<T>(string source, FixxParserFormat format) where T : IFixxDalObject, new()
		{
			return new FixxParser<T>().ParseIEnumerable(source, format);
		}
	}

	public class FixxParser<T> : IFixxParser<T> where T : IFixxDalObject, new() 
	{
		public FixxParser () 
		{
		}
		public IEnumerable<T> ParseIEnumerable(string source)
		{
			return this.ParseIEnumerable(source, FixxParserFormat.XML);
		}
		public IEnumerable<T> ParseIEnumerable(string source, FixxParserFormat format)
		{
		
		
			List<T> t = new List<T>();
			if (string.IsNullOrEmpty(source))
				return t;
			
			if (format == FixxParserFormat.JSON)
			{
				return JsonConvert.DeserializeObject<IEnumerable<T>>(source);
			}
			else
			{
				XElement el = XElement.Parse(source);
				foreach (var e in el.Elements())
				{
					var serializer = new DataContractSerializer(typeof(T));

					using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(e.ToString())))
					{
						var o = (T)serializer.ReadObject(memoryStream);
						memoryStream.Close();
						t.Add(o);
					}
				}
			}
			return t;
		}
		
		
		
		public T Parse(string source)
		{
			return this.Parse(source, FixxParserFormat.XML);
		}
		public T Parse(string source, FixxParserFormat format)
		{
			T t = default(T);
			if (string.IsNullOrEmpty(source))
				return t;
			if (format == FixxParserFormat.JSON)
			{
				return JsonConvert.DeserializeObject<T>(source);
			}
			else
			{
				XElement el = XElement.Parse(source);

				var serializer = new DataContractSerializer(typeof(T));
				
				using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(source)))
				{
					t = (T)serializer.ReadObject(memoryStream);
					memoryStream.Close();
				}
				if (t != null)
				{
					return t;
				}
			}
			return default(T);
		}
	}
}
